package dao

import (
	"context"
	"fmt"
	"time"

	"github.com/redis/go-redis/v9"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"gorm.io/gorm/schema"

	"shorten/pkg/setting"
)

var (
	db  *gorm.DB
	rdb *redis.Client
)

const (
	URL_KEY = "shorten:url"
)

func DB() *gorm.DB {
	return db
}

func Redis() *redis.Client {
	return rdb
}

func InitDBEngine(cfg *setting.DBSettingsS) (err error) {
	dsn := "%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=%t&loc=Local"
	//db链接参数
	dsn = fmt.Sprintf(dsn,
		cfg.UserName,
		cfg.PassWord,
		cfg.Host,
		cfg.Port,
		cfg.DB,
		cfg.Charset,
		cfg.ParseTime,
	)
	//gorm的额外配置
	extraConf := &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			TablePrefix:   cfg.Prefix, //设置表前缀
			SingularTable: true,       //表名称不使用复数
		},
		PrepareStmt: true, //全局模式，所有 DB 操作都会创建并缓存预编译语句
	}
	//设置是否打印sql
	if cfg.Log == true {
		extraConf.Logger = logger.Default.LogMode(logger.Info)
	}
	db, err = gorm.Open(mysql.Open(dsn), extraConf)
	if err != nil {
		return err
	}
	sqlDb, err := db.DB()
	if err != nil {
		return err
	}
	sqlDb.SetMaxOpenConns(cfg.MaxOpenConns)                                //设置打开数据库链接的最大数量
	sqlDb.SetMaxIdleConns(cfg.MaxIdleConns)                                //设置空闲连接池中链接的最大数量
	sqlDb.SetConnMaxLifetime(time.Minute * time.Duration(cfg.MaxLifetime)) //设置链接可复用的最大时间
	return err
}

func InitRDB(cfg *setting.RedisSettingsS) (err error) {
	rdb = redis.NewClient(&redis.Options{
		Addr:     cfg.Addr,
		DB:       cfg.DB,
		Password: cfg.Auth,
	})
	_, err = rdb.Ping(context.TODO()).Result()
	return
}

func CommonHashGet(ctx context.Context, key, field string) string {
	return Redis().HGet(ctx, key, field).Val()
}

func CommonHashSet(ctx context.Context, key, field, value string) error {
	return Redis().HSet(ctx, key, field, value).Err()
}

type Dao struct {
	engine *gorm.DB
}

func New() *Dao {
	return &Dao{
		engine: db,
	}
}
